from langchain.memory import ChatMessageHistory
memory = ChatMessageHistory()
memory.add_user_message("妳好")
memory.add_ai_message("妳好, 有什麼需要幫忙的嗎?")
print(memory.messages)
[HumanMessage(content='妳好'), AIMessage(content='妳好, 有什麼需要幫忙的嗎?')]
from langchain_core.messages import (
AIMessage,
HumanMessage,
SystemMessage
)
from rich import print as pprint
def print_messages(history):
for message in history.messages:
pprint(message)
memory.add_messages([
AIMessage('沒關係, 你可以隨時找我'),
HumanMessage('好的')
])
print_messages(memory)
HumanMessage(content='妳好')
AIMessage(content='妳好, 有什麼需要幫忙的嗎?')
AIMessage(content='沒關係, 你可以隨時找我')
HumanMessage(content='好的')
memory.clear()
print_messages(memory)
from langchain_core.prompts import MessagesPlaceholder # 是一個佔位符,用於在模板中插入動態內容,例如對話歷史
prompt = ChatPromptTemplate.from_messages( # 創建一個聊天提示模板
[
("system", "你是個聊天助理, 請根據問題作回應"),
MessagesPlaceholder(variable_name="history"), # 在模板中插入了一個名為 history 的佔位符。這個佔位符將在對話歷史中插入之前的訊息
("human", "{input}"),
]
)
chain = prompt | chat_model # 將聊天提示模板 prompt 與聊天模型 chat_model 結合
from langchain_core.runnables.history import RunnableWithMessageHistory # 用於將 Runnable 物件與訊息記憶功能結合,從而能夠處理包含對話歷史的對話流程
memories = {'0': memory, '1': ChatMessageHistory()} # 定義了一個字典 memories,其中包含了不同會話的記憶體。每個記憶體對應一個 session_id,例如 '0' 和 '1'
# '0': memory 表示一個預先定義的 memory 物件、'1': ChatMessageHistory() 表示一個新的對話歷史記錄物件,專門用於存儲會話歷史
# 所以要記錄同一個訊息歷史就用0,想要用新的對話紀錄就用1
chat_history = RunnableWithMessageHistory(
chain, # 前面定義的聊天處理鏈(包含提示模板和聊天模型)
lambda session_id: memories[session_id], # 根據會話 ID (session_id) 從 memories 字典中提取相應的記憶體物件。這確保了不同的會話可以使用不同的歷史記錄。
input_messages_key="input",
history_messages_key="history",
)
chat_history.invoke(
{"input": "Stephen Curry今日帶領美國男籃贏得2024奧運籃球冠軍"},
config={"configurable": {"session_id": "0"}} # 指定會話 ID (session_id) 為 '0',所以這次對話會使用 memories 中 '0' 對應的記憶體物件來存儲和檢索對話歷史
).content # 取這個結果中的文本內容
'這真是個令人興奮的消息!Stephen Curry一直以來都是一位出色的球員,能夠帶領美國男籃贏得2024奧運籃球冠軍無疑是他職業生涯中的一大亮點。不知道你是否有看比賽,覺得他的表現如何呢?'
chat_history.invoke(
{"input": "我剛剛說2024奧運籃球冠軍是誰?誰是主要角色?"},
config={"configurable": {"session_id": "0"}} # 再次指定會話 ID 為 '0',因此系統會從 memories['0'] 中檢索對話歷史
).content
'你剛剛說Stephen Curry帶領美國男籃贏得了2024奧運籃球冠軍。Stephen Curry顯然是這次勝利中的主要角色之一,他的出色投籃技術和領導能力無疑對球隊的成功起到了關鍵作用。如果你有更多關於比賽的細節,歡迎分享!'
chat_history.invoke(
{"input": "我剛剛說2024奧運籃球冠軍是誰?誰是主要角色?"},
config={"configurable": {"session_id": "1"}} # 再次指定會話 ID 為 '0',因此系統會從 memories['0'] 中檢索對話歷史
).content
'截至目前為止,我還無法提供2024年奧運籃球冠軍的資訊,因為2024年的奧運會尚未舉行。奧運籃球比賽通常在夏季奧運會期間進行,屆時才會知道哪個國家贏得冠軍以及誰是主要的明星球員。\n\n如果你有其他問題或是想聊其他話題,我很樂意幫助你!'
恭喜! 我們成功讓LLM記得先前的對話啦!!
那我們有沒有辦法讓每次對答紀錄也能儲存在DB中呢?
當然有,下一章我們將來探討!